package com.chu.cloud.service.impl;

import com.chu.cloud.dto.MemberGetCouponDto;
import com.chu.cloud.entity.MemberCoupon;
import com.chu.cloud.enums.CouponEnum;
import com.chu.cloud.repository.MemberCouponRepository;
import com.chu.cloud.repository.UserRepository;
import com.chu.cloud.service.MemberCouponService;
import com.chu.cloud.stream.channel.CouponNumReduceProcessor;
import com.chu.cloud.stream.payload.OrderCouponUseLoad;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @author: TianShu.CHU
 * @CreateDate: 2018-05-03 23:02
 * @Version: 1.0
 */
@Service
@Slf4j
public class MemberCouponServiceImpl implements MemberCouponService {

    @Autowired
    private MemberCouponRepository memberCouponRepository;

    @Autowired
    private CouponNumReduceProcessor couponNumReduceProcessor;

    /**
     * 优惠券领取,只能新增一条记录,同一用户领取同一个优惠券,数量不能++
     * 因为,有OderNo字段,用户领取了两张相同的优惠券,可使用在不同的订单上
     * <p>
     *      跨微服务事务:
     *          1.确保消息可靠性投递
     *          2.积分微服务受到用户领劵消息,入库成功之后才发送消息给营销微服务减数量
     *          3.营销微服务出现异常,调用积分微服务用户领劵的回滚接口
     * </p>
     *
     * @param couponDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUserCoupon(MemberGetCouponDto couponDto) {
        try {
            if (couponDto.getEndTime().compareTo(new Date()) < 0){
                log.error("已过领取时间,不可领取");
                return;
            }
            List<MemberCoupon> memberCoupons = memberCouponRepository.findByMemberIdAndCouponDiscountId(
                    couponDto.getMemberId(), couponDto.getId());
            if (memberCoupons.size() < couponDto.getLimitReceive()) {
                //用户已领取的数量小于该优惠券最大领取数量,插入一条数据
                MemberCoupon memberCoupon = new MemberCoupon();
                memberCoupon.setCouponDiscountId(couponDto.getId());
                memberCoupon.setCouponDiscountName(couponDto.getDiscountName());
                memberCoupon.setUseStartDate(couponDto.getEffectStartTime());
                memberCoupon.setExpirationDate(couponDto.getEffectEndTime());
                memberCoupon.setMemberId(couponDto.getMemberId());
                memberCoupon.setShopId(couponDto.getShopId());
                memberCoupon.setCouponNum(1);
                memberCoupon.setStatus(CouponEnum.GET);
                MemberCoupon save = memberCouponRepository.save(memberCoupon);
                //发送消息到营销服务减数量
                Message<Integer> message = MessageBuilder.withPayload(couponDto.getId()).build();
                couponNumReduceProcessor.output().send(message);
            }

        } catch (Exception e) {
            log.error("用户:{}领取优惠券:{}出现异常:{}", e);
            return;
        }

    }

    @Override
    public void useCoupon(OrderCouponUseLoad payLoad) {
        List<MemberCoupon> memberCoupons = memberCouponRepository.findByIdIn(payLoad.getCouponIds());
        if (!CollectionUtils.isEmpty(memberCoupons)) {
            memberCoupons.forEach(memberCoupon -> {
                memberCoupon.setOrderNo(payLoad.getOrderNo());
                memberCoupon.setStatus(CouponEnum.USED);
                memberCouponRepository.save(memberCoupon);

            });
        }
    }
}
